(function( window ,$) {
	/**
	 * 可扩展
	 */
	$.fn.selfGrid =   {  
			method : {},
			event  : {},
	}; 
	
	/**
	 * 表格data存储数据为 $("table").data("info",{"result":[{status:1,editing:1,row:{}}],"options":{}});
	 * status  : 数据状态   -1 = 被删除 ;  0 = 未处理 ; 1 = 修改  ; 2 = 新增 
	 * editing : 行状态     0 = 处于非编辑状态  ;  1 = 正在编辑
	 **/   
})(window,jQuery);



//扩展事件
(function( window ,$) { 
    $.extend($.fn.selfGrid.event,
    		{
	    	 onClickRow : function(element,options){    
				var result = element.data("info").result;  
				element.on("click","tr",function(event){  
	                  var target =  this; 
					  options.onClickRow(target.rowIndex-1,result[target.rowIndex-1].row,target);
				 });
			  },
			  onClickOperation : function (element,options){  
				 var panel = $(element).parents("div.panel");
				 var opts  = panel.find("div.panel-heading span.operation");
				 opts.on("click",function(event){  
					 var target = $(this);
					 var op = target.attr("op");
					 //后续 在 扩展方法中实现
					 if($.fn.selfGrid.method.hasOwnProperty(op)){
						 $.fn.selfGrid.method[op](element,options,target);
					 }
				 });
	          }
            }  
    ); 
})(window,jQuery);



//扩展方法
(function( window ,$) {
/**
 *   第一个参数为表格对象 $telement
 *   第二个参数为数组  参数数组即为重新该方法的所有参数放进一个数组里边
 **/	
 $.extend($.fn.selfGrid.method,
		 {
	       beginEditRow  : function (){  
	    	   
	    	  var  $telement = $(arguments[0]) , rowIndex = arguments[1][1],
	    	       info = $telement.data("info"),
   	               options = info.options,
   	               result = info.result[rowIndex];
	               data =  result.row,
	    	       row =  $telement.find("tbody>tr:eq("+rowIndex+")");
	    	 
	    	   if( !row || row.length < 1 ||  result["editing"] ) return;
	    	   
	    	   else  result["editing"] = 1 ; 
	    	     
	    	   var  height = row.height()-4 ,
	    	        columns = options.columns,
    	            rws = info.headWidth; 
	    	   
	    	   for(var i = 0 ,l = columns.length ; i < l ; i++){ 
	    	       var c = columns[i]; 
	    		   
	    	       if(!c.editor) continue; 
	    		   
	    		   else if($.type(c.editor) == "boolean"){
	    			
	    			   c.editor = {};
	    			   c.editor.type = "text";
	    		   } 
	    	       
	    		   var column = row.find("td:eq("+i+")") , width = c.width ? c.width : rws[i] ;
	    		   
	    		   var   val = (data[c.field] || data[c.field] === 0) ? data[c.field] : (c.value || c.value === 0 ? c.value  : "")   ;
					
	    		   
	    		   switch (c.editor.type) { 
	    		   
	    		   case "text":   
	    			   var target = "<input    style='width:"+width+"px'   type='text' value='"+val+"'/>"; 
				    	   column.html(target);
				    	   break; 
				    	  
				      case "password":   
				    	var target = "<input  style='width:"+width+"px' type='password' value='"+val+"'/>"; 
				    	    column.html(target); 
						    break; 
						    
				      case "date":   
				    	var target = "<input style='width:"+width+"px'  type='text' value='"+val+"' class='Wdate'  />"; 
				    	    column.html(target); 
						    break; 
						  
				      case "select":
				    	  width =  width < 75 ? 75 : width ;
				    	  var target = "<select  style='width:"+width+"px' ><option value=''>请选择</option>";  
						      
				    	  if(c.editor.data){   
							      for(var ii = 0 , ll = c.editor.data.length ; ii < ll ; ii++){
								     var  selectHtml = ( val || val === 0) && (val == c.editor.data[ii][c.editor.fieldValue])  ? "selected='selected'":"";
								     target += "<option "+selectHtml+" value = '"+c.editor.data[ii][c.editor.fieldValue]+"'>"+c.editor.data[ii][c.editor.filedText]+"</option>";  
							      } 
						     }
						    target +=  "</select>" ;
						    column.html(target);
						  break; 
	    	       }
	    	   
	    	     } 
	           },
	           endEditRows : function(){  
	        	   var selfGrid = this;
	        	   var $telement = $(arguments[0]);
	        	   var info = $telement.data("info");
	        	   var result = info.result;
	        	   
	        	   for(var i = 0 , l = result.length ; i < l ; i++){
	        		    
	        		   if(!result[i].editing) continue; 
	        		   selfGrid.endEditRow($telement,["endEditRow",i]);
	        		   
	        	   }
	        	    
	           },
	           endEditRow : function(){ 
	        	   var $telement = $(arguments[0]) ,rowIndex = arguments[1][1],
	        	   
		        	   row = $telement.find("tbody>tr:eq("+rowIndex+")"),
		        	   
		        	   info =  $telement.data("info") ,
		        	   
		    	       options = info.options,
		    	       
		    	       result = info.result[rowIndex],
		    	       
		    	       data = result.row; 
	        	   
		            if(!row || row.length < 1 ||  result["editing"] < 1 ) return;
		             
	        	    for(var i = 0 ,l = options.columns.length ; i < l ; i++){
	        	     
	        		   var column = row.find("td:eq("+i+")"),
	        		       c = options.columns[i]; 
	        		   
	        		   if(!c.editor) continue ; 
	        		   switch (c.editor.type) {
			    		   case "select":   
			    			   
			    			   var  select = column.find("select"); 
			    			        data[options.columns[i]["field"]] = select.val() ;
			    			   
			    			   if(select.val()){
			    				   column.html(select.find("option:selected").text());
			    			   } else{
			    				   column.html('');
			    			   }
						       break;
						       
						    default : 
						    	
						    	var  val = column.find("input").val();
						             data[options.columns[i]["field"]] = val ;
						    	     column.html(val);
						    	break;
	        		     }  
	        	   }; 
	        	   result.editing = 0;   
	           },
	           addRows  : function (){
	        	   
                   var  $telement = $(arguments[0]) , data = arguments[1][1];
	        	   
	        	   var  options = $telement.data("info").options; 
	        	   
	        	   var   data = $.fn.selfgrid("getMethod","init_tbody")($telement,options,data); 
	        	   
	        	   var result = $.fn.selfgrid("getMethod","init_data")(data);
	        	   
	        	   $.fn.selfgrid("getMethod","cache_info")($telement,options,result);
	        	   
	           },
	           updateRows : function(){
	        	  
	        	   var  $telement = $(arguments[0]) , rows = arguments[1][1];
	        	   
	        	   var updateRow = this.updateRow;
	        	   
	        	   for(var i = 0 , l = rows.length ; i < l ; i++){
	        		   
	        		   updateRow($telement,["updateRow",rows[i].data,rows[i].rowIndex]);
	        	   }
	        	   
	        	   
	           }, 
	           updateRow : function(){
	        	    
	        	   if(rowIndex < 0) return ;
	        	   
	        	   var  $telement = $(arguments[0]) , row = arguments[1][1] , rowIndex = arguments[1][2];
	        	        result = $telement.data("info").result;
	        	   
	        	   if(!result[rowIndex]) return ;
	        	   
	        	   result[rowIndex].status = 1 ;
	        	   
	        	   $.extend(result[rowIndex].row,row);
	        	   
	        	   var row = result[rowIndex].row;
	        	   
	        	   var headColumns = $telement.find("thead tr:eq(0) td");
	        	  
	        	   var bodyColumns = $telement.find("tbody tr:eq("+rowIndex+") td");
	        	  
	        	   for(var i = 0 , l = headColumns.length ; i < l ; i++){
	        		   
	        		  var field = $(headColumns[i]).attr("field");
	        		  
	        		  if(!field && field !== 0) continue ;
	        		  
	        		   $(bodyColumns[i]).html(row[field]); 
	        		  
	        	   } 
	           },
	           getAllData : function(){  
	        	   
	        	   var  datas = [] ,  $telement = $(arguments[0]) ,  result = $telement.data("info").result;
 
	        	   for(var i = 0 , l = result.length ; i < l ; i++){ 
	        	    	   datas.push(result[i].row); 
	        	   }
	        	   return datas; 
	        	   
	           }
		 }); 

})(window,jQuery);





(function( window ,$) {
	/** 表格默认属性 **/
	var operation = [
		 {"method":"addRow"    ,"op":"add"   ,"icon":"icon-add"},   {"method":"bgeinEditRows","op":"edit"  ,"icon":"icon-edit"},
		 {"method":"endEditRows","op":"ok"    ,"icon":"icon-ok"},   {"method":"removeRows"  ,"op":"remove","icon":"icon-remove"},
		 {"method":"searchRow" ,"op":"search","icon":"icon-search"},{"method":"reloadRow","op":"reload","icon":"icon-reload"}
		]; 
	
	var s_g_o = $.extend({},
			{
			data   :  null,
			title  :  "",
			url    :  "",
			tableClass     :  "table table-striped  table-bordered  table-hover table-condensed",
			tdhi   :  "td-hidden",
			pagination : true,
			operation  : null,
			seach      : false,
			onClickRow  : null,
			beginEdit : null,
			endEdit   : null,
			cancelEdit: null,
			columns   : null,
			column : 
			 {
				title : "",
			/*	check*/
				field : "",
				width : "",
				align : "",
				formatter : null,
				hidden : false,
				checkbox : false, 
				editor : {
					type : "text" ,
					fieldValue : "key" ,
					filedText : "value" ,
					value : "" ,
					data :null ,
				 } 
			   } 
		    }
	);
	
	/** 初始化 表格 属性 、数据等 **/
	var _self_grid = function(element,options){ };
	
	   /** 渲染表格 **/
	   _self_grid.prototype = {
			   
			   init : function(element,options){
				   
				   var $telement = $(element);
				   
				   var opts = this.init_options(options);
				   
				   opts.data = opts.data || [];
				   
				   var result = this.init_data(opts.data);
				   
				   var $element =  this.init_table($telement,opts);
				   
				   this.init_panel($element,opts);
				   
				   this.init_thead($telement,opts);
				   
				   this.init_tbody($telement,opts,opts.data);
				   
				   this.cache_info($telement,opts,result);
				   
				   this.init_event($telement,opts); 
				   
			   },
			   
			   init_options : function(options){  
				       options = $.extend({},s_g_o,options);
					   // 初始化列信息
					   var column  = options.column ; 
					   for(var i = 0 ,len = options.columns.length ; i < len ; i++){
						   var editor = options.columns[i].editor;
						   options.columns[i] = $.extend(true,{},column,options.columns[i]); 
				        	if(!editor) { 
				        		options.columns[i].editor = null;
				        	}   
				        }   
					   //初始化表格操作
				        if(options.operation){
				        	 options.onClickOperation = $.fn.selfGrid.event.onClickOperation;
				        } 
					    //删除多余属性
				        delete options.column;  
				        return options;
			    },
			    
			   /**格式化 数据*/
			    init_data : function (data){  
			        //存储数据
	                var result = [];
	                for(var i = 0 , l = data.length ; i <l ; i++ ){
	                	// status  -1 = 被删除 ;  0 = 未处理 ; 1 = 修改  ; 2 = 新增   |  editing  0 = 非编辑状态  ; 1 = 正在编辑 
	                	result.push({status : 0, editing : 0, row : data[i]}); 
	                }   
	                return result; 
			   }, 
			   /**初始化 表格**/
			   init_table : function($telement,options){ 
				   var $element = $telement;
			       if($element[0].tagName != "TABLE"){
			    	   $element.append("<table></table>");        	  
			    	   $telement = $($element).find("table:first");
			       }   
			       $telement.addClass(options.tableClass); 
			       return $element ;
			   },
			   
			   /**初始化 panel**/
			   init_panel  : function($element,options){
					var  panel =  "<div class='panel   panel-primary'><div class='panel-heading'>", 
					     opts  =  options,
				         columns  = opts.columns,
				         content = null;
					//初始化 操作
					$.each(operation,function(i,e){ 
					        var op = e.op; 
					        if(!opts.operation){ return ;}
	                	    for(var i = 0 ; i < opts.operation.length ; i++){
	                	    	if($.type(opts.operation[i]) == "string"){
	                	    		if(op == opts.operation[i]){
	                	    			panel+="<span op='"+e.method+"' class='operation  "+e.icon+"'></span>";
	                    	    		break;
	                	    		} 
	                	    	}else if($.type(opts.operation[i]) == "object"){ 
	                	    		if(opts.operation[i].op == op){
	                	    			var opm = $.extend({},e,opts.operation[i]); 
	                	    			panel+="<span op='"+opm.method+"'class='operation   "+opm.icon+"'></span>";
	                    	    		break;
	                	    		}
	                	    	 } 
	                          }
					   }); 
					panel += "</div><div class='panel-body' style='padding: 0px;'></div><div class='panel-footer' style='display:none'>Panel footer</div></div>";   
					
					var $panel = $(panel);
					$element.after($panel); 
					$panel.find(".panel-body").prepend($element); 
			   }, 
			   
			   /** 初始化 表头 **/
			   init_thead : function($telement,options){
				    var  columns  = options.columns,
				         theadHtml = "<thead><tr>";
					for(var i = 0 ,len = columns.length ; i < len ; i++){ 
						 var c = columns[i];
						     hidden = c.hidden ? "class="+options.tdhi+" " :""; //field="+c.field+"
						     var s = c.width ? "style='widht:"+c.width+"'" : "";
						     theadHtml+="<td  field='"+c.field+"' "+hidden+" >"+c.title+"</td>";
					 }
					 theadHtml  +="</tr></thead>"; 
					 $telement[0].innerHTML = theadHtml;
					 //计算宽度 
					 var columns = $telement.find("thead>tr>td");
					 for(var i = 0 , l = columns.length ; i < l ; i++){
						 var colum = $(columns[i]);
						 colum.css("min-width",colum.width()+"px");
					 } 
			   },
			   
			   init_tbody : function($telement,options,data){
				 
					var columns   =   options.columns,  
				        tbodyHtml = ""; 
					 for(var j =0 ,l = data.length ; j < l ; j++){ 
						 var row = data[j];
						     tbodyHtml += "<tr>";  
						 for(var i = 0 ,len = columns.length ; i < len ; i++){  
							 var c =  columns[i] ,
						         hidden = c.hidden ? options.tdhi :"",
							     text = row[c.field] ,
							     defValue = columns[i]["value"] ; 
						         text = data[j][c.field] = (text || text === 0 ? text : defValue || defValue ===0 ? defValue : "");
							     if(c.formatter && $.type(c.formatter) == "function"){
							    	 text = c.formatter(text,row,j);
							     }   
							 tbodyHtml+="<td  class='"+hidden+"' >"+text+"</td>";	  
						 }
						 tbodyHtml += "</tr>"; 
					 }
					 var tbody = $telement.find("tbody");
					 if(tbody.length < 1){ 
						  $telement[0].innerHTML = ($telement.find("thead")[0].outerHTML+"<tbody>"+tbodyHtml+"</tbody>"); 
					 }else{
						 $telement.find("tbody").append(tbodyHtml); 
					 } 
					 return data;
			   },
			   
			   /** telement = 表格对象 ;  data = 数据  ;  options = 参数 **/
			   cache_info : function($telement,options,result){ 
	                 var info =  $telement.data("info");
	                 if(!info){
	                	 var rws = [];
	     	            trcs =  $telement.find("thead>tr:eq(0)>td"); 
	    	    	    for(var i = 0 ,l = options.columns.length ; i < l ; i++)
	    	    	    { 
	    	    	    	rws[i] = $(trcs[i]).width(); 
	    	    	    } 
	                	 $telement.data("info",{"options" : options, "result" : result,"headWidth" : rws});
	                 }else{
	                	 info.result.push.apply(info.result,result);
	                 } 
			   }, 
			   
			   /** 绑定事件 **/
			   init_event : function($telement,options){  
                   var event = $.fn.selfGrid.event;
                   for(var e in options){
            	      if(event.hasOwnProperty(e)){
            		   event[e]($telement,options);
            	      }
                   }
			   }
	    }
	
	   
	   $.fn.selfgrid = function (options) {   
		    var type = $.type(options);
			if(type == "object"){ 
		    	  var _sg = new _self_grid();  
		          _sg.init(this, options); 
			}else if( type == "string" && options == "getMethod" ){//为了能访问到 _self_grid 里边的方法
				var _sg = new _self_grid(); 
				var method = arguments[1];
				if($.type(_sg[method]) == "function") return _sg[method];
				
		     }else if(type == "string" && options != "getMethod"){
				   var $telement = $(this); 
		           if($telement[0].tagName != "TABLE")    $telement = $(this).find("table:first"); 
				   if($.type($.fn.selfGrid.method[options]) != "function") return; 
				   return   $.fn.selfGrid.method[options]($telement,arguments);
		     }  
       };  
})(window,jQuery); 
